[id].vue 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. <script setup>
  2. import { ref, onMounted } from "vue";
  3. import { useRoute, useRouter } from "vue-router";
  4. const { getMediaUrl } = useImage();
  5. const config = useRuntimeConfig();
  6. definePageMeta({
  7. layout: "blank",
  8. });
  9. const route = useRoute();
  10. const router = useRouter();
  11. const { get } = useApi();
  12. const { getImageUrl } = useImage();
  13. const { getTeamName, getPositionName } = useSalesData();
  14. const staff = ref(null);
  15. const showrooms = ref([]);
  16. // 데이터 로드
  17. const loadData = async () => {
  18. const id = route.params.id;
  19. // 영업사원 정보
  20. const { data: staffData } = await get(`/staff/sales/${id}`);
  21. if (staffData?.success && staffData?.data) {
  22. staff.value = staffData.data;
  23. }
  24. // 전시장 리스트
  25. const { data: branchData } = await get("/branch/list", { per_page: 1000 });
  26. if (branchData?.success && branchData?.data) {
  27. showrooms.value = branchData.data.items || [];
  28. }
  29. };
  30. // 전시장 이름 가져오기
  31. const getShowroomName = (showroomId) => {
  32. const showroom = showrooms.value.find((s) => s.id === showroomId);
  33. return showroom ? showroom.name : "-";
  34. };
  35. // 프린트
  36. const handlePrint = () => {
  37. window.print();
  38. };
  39. // 닫기
  40. const handleClose = () => {
  41. window.close();
  42. };
  43. onMounted(() => {
  44. loadData();
  45. });
  46. </script>
  47. <template>
  48. <div class="sales--print-page">
  49. <div class="sales--print-container">
  50. <!-- 헤더 -->
  51. <div class="sales--print-header">
  52. <h1>아우디 공식딜러 포드코리아</h1>
  53. <div class="FORDKOREA--logo"><img :src="getMediaUrl('/img/FORDKOREA_logo.png')" /></div>
  54. </div>
  55. <!-- 메인 콘텐츠 -->
  56. <div class="sales--print-content">
  57. <!-- 사진 영역 -->
  58. <div class="sales--print-photo">
  59. <img
  60. v-if="staff?.photo_url"
  61. :src="getImageUrl(staff.photo_url)"
  62. :alt="staff.name"
  63. />
  64. <div v-else class="sales--print-photo-empty">사진없음</div>
  65. </div>
  66. <!-- 정보 영역 -->
  67. <div class="sales--print-info">
  68. <div class="sales--print-row">
  69. <div class="sales--print-label">전시장</div>
  70. <div class="sales--print-value">{{ getShowroomName(staff?.showroom) }}</div>
  71. </div>
  72. <div class="sales--print-row">
  73. <div class="sales--print-label">팀</div>
  74. <div class="sales--print-value">{{ getTeamName(staff?.team) }}</div>
  75. </div>
  76. <div class="sales--print-row">
  77. <div class="sales--print-label">이름</div>
  78. <div class="sales--print-value sales--print-name">{{ staff?.name }}</div>
  79. </div>
  80. <div class="sales--print-row">
  81. <div class="sales--print-label">직책</div>
  82. <div class="sales--print-value">{{ getPositionName(staff?.position) }}</div>
  83. </div>
  84. <!-- <div class="sales--print-row">
  85. <div class="sales--print-label">대표번호</div>
  86. <div class="sales--print-value">{{ staff?.main_phone }}</div>
  87. </div> -->
  88. <div class="sales--print-row">
  89. <div class="sales--print-label">핸드폰</div>
  90. <div v-if="config.public.company == 'w'" class="sales--print-value">
  91. {{ staff?.main_phone }}
  92. </div>
  93. <div v-else class="sales--print-value">{{ staff?.direct_phone }}</div>
  94. </div>
  95. <div class="sales--print-row">
  96. <div class="sales--print-label">이메일</div>
  97. <div class="sales--print-value">{{ staff?.email }}</div>
  98. </div>
  99. </div>
  100. </div>
  101. <!-- 프린트 버튼 (프린트 시 숨김) -->
  102. <div class="sales--print-actions no-print">
  103. <button class="sales--print-btn" @click="handlePrint">프린트</button>
  104. <button class="sales--print-btn sales--print-btn-secondary" @click="handleClose">
  105. 닫기
  106. </button>
  107. </div>
  108. </div>
  109. </div>
  110. </template>
  111. <style scoped>
  112. .FORDKOREA--logo {
  113. img {
  114. max-height: 50px;
  115. }
  116. }
  117. .sales--print-page {
  118. min-height: 100vh;
  119. background: #f5f5f5;
  120. padding: 20px;
  121. }
  122. .sales--print-container {
  123. max-width: 800px;
  124. margin: 0 auto;
  125. background: white;
  126. padding: 40px;
  127. box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  128. }
  129. .sales--print-header {
  130. text-align: center;
  131. margin-bottom: 40px;
  132. padding-bottom: 20px;
  133. border-bottom: 2px solid #333;
  134. display: flex;
  135. align-items: center;
  136. justify-content: space-between;
  137. }
  138. .sales--print-header h1 {
  139. font-size: 28px;
  140. font-weight: bold;
  141. color: #000;
  142. margin: 0;
  143. }
  144. .sales--print-content {
  145. display: flex;
  146. gap: 40px;
  147. margin-bottom: 40px;
  148. }
  149. .sales--print-photo {
  150. flex-shrink: 0;
  151. width: 200px;
  152. height: 300px;
  153. border: 1px solid #ddd;
  154. border-radius: 8px;
  155. overflow: hidden;
  156. display: flex;
  157. align-items: center;
  158. justify-content: center;
  159. background: #f9f9f9;
  160. }
  161. .sales--print-photo img {
  162. width: 100%;
  163. height: 100%;
  164. object-fit: cover;
  165. }
  166. .sales--print-photo-empty {
  167. color: #999;
  168. font-size: 14px;
  169. }
  170. .sales--print-info {
  171. flex: 1;
  172. display: flex;
  173. flex-direction: column;
  174. gap: 20px;
  175. }
  176. .sales--print-row {
  177. display: flex;
  178. align-items: center;
  179. padding-bottom: 12px;
  180. border-bottom: 1px solid #e0e0e0;
  181. }
  182. .sales--print-label {
  183. width: 120px;
  184. font-weight: bold;
  185. color: #333;
  186. font-size: 15px;
  187. }
  188. .sales--print-value {
  189. flex: 1;
  190. color: #555;
  191. font-size: 15px;
  192. }
  193. .sales--print-name {
  194. font-size: 18px;
  195. font-weight: bold;
  196. color: #000;
  197. }
  198. .sales--print-actions {
  199. display: flex;
  200. justify-content: center;
  201. gap: 12px;
  202. margin-top: 40px;
  203. }
  204. .sales--print-btn {
  205. padding: 12px 32px;
  206. font-size: 16px;
  207. font-weight: bold;
  208. border: none;
  209. border-radius: 4px;
  210. cursor: pointer;
  211. background: #000;
  212. color: white;
  213. transition: background 0.2s;
  214. }
  215. .sales--print-btn:hover {
  216. background: #333;
  217. }
  218. .sales--print-btn-secondary {
  219. background: #666;
  220. }
  221. .sales--print-btn-secondary:hover {
  222. background: #888;
  223. }
  224. /* 프린트 스타일 */
  225. @media print {
  226. .sales--print-page {
  227. background: white;
  228. padding: 0;
  229. }
  230. .sales--print-container {
  231. max-width: none;
  232. box-shadow: none;
  233. padding: 20px;
  234. }
  235. .no-print {
  236. display: none !important;
  237. }
  238. .sales--print-header {
  239. margin-bottom: 30px;
  240. }
  241. .sales--print-content {
  242. margin-bottom: 0;
  243. }
  244. }
  245. </style>